home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / packet / p_aa4re / mbb35src / 8250svcx.asm < prev    next >
Encoding:
Assembly Source File  |  1991-02-17  |  29.0 KB  |  617 lines

  1. ;==========================================================================;
  2. ; 8250 Extended functions                                                  ;
  3. ;                                                                          ;
  4. ;   Copyright 1983 by William E. Westfield.  All rights reserved.          ;
  5. ;   Copyright 1986, 1988, 1991 by H. Roy Engehausen.  All rights reserved. ;
  6. ;   This software may be freely distributed and used, but it may not       ;
  7. ;   under any circumstances be sold by anyone other than the author.       ;
  8. ;   It may be distributed by a commercial company as long as it is         ;
  9. ;   for no cost.                                                           ;
  10. ;                                                                          ;
  11. ;  AH = 4     Inquiry                                                      ;
  12. ;  ------------------                                                      ;
  13. ;  AH returns 0AAH.  AL returns 055H.  This call is used to see if this    ;
  14. ;  driver has been loaded for a particular port.                           ;
  15. ;                                                                          ;
  16. ;  AH = 5     Drop RTS                                                     ;
  17. ;  -------------------                                                     ;
  18. ;  This drops DTR (pin 20) and RTS (pin 4).  Used to tell the TNC not to   ;
  19. ;  send any more information.  TNC-1 and PK-232 use pin 4 for handshaking. ;
  20. ;  TNC-2 uses pin 20 (dont ask me why!)  No return value.                  ;
  21. ;                                                                          ;
  22. ;  AH = 6     Raise RTS                                                    ;
  23. ;  --------------------                                                    ;
  24. ;  Raise DTR and RTS.  No return value.                                    ;
  25. ;                                                                          ;
  26. ;  AH = 7     Send Break                                                   ;
  27. ;  ---------------------                                                   ;
  28. ;  Generates a "Break".  No return value.                                  ;
  29. ;                                                                          ;
  30. ;  AH = 8     Non-destructive Read                                         ;
  31. ;  -------------------------------                                         ;
  32. ;  Returns the next character in the buffer in AL without removing it from ;
  33. ;  the buffer.  AH value same as code 1.  No check for character ready     ;
  34. ;                                                                          ;
  35. ;  AH = 9     Set/Get options                                              ;
  36. ;  --------------------------                                              ;
  37. ;  Set the current option byte to AL returning the old option byte in AL.  ;
  38. ;                                                                          ;
  39. ;  AH = A     Write buffer                                                 ;
  40. ;  -----------------------                                                 ;
  41. ;  Sends CX characters starting at DI:ES                                   ;
  42. ;                                                                          ;
  43. ;  AH = B     Read buffer                                                  ;
  44. ;  ----------------------                                                  ;
  45. ;  Receives up to CX characters starting at DI:ES.  CX set to actual       ;
  46. ;  count read                                                              ;
  47. ;                                                                          ;
  48. ;  AH = C     Send/Receive DED Hostmode buffer                             ;
  49. ;  -------------------------------------------                             ;
  50. ;  Not implemented for 8250                                                ;
  51. ;                                                                          ;
  52. ;==========================================================================;
  53.  
  54. ;==========================================================================;
  55. ; Inquiry                                                                  ;
  56. ;==========================================================================;
  57.  
  58. rsint_8250_inquiry:
  59.  
  60.         MOV     AX,0AA55H           ; Set footprint
  61.         JMP     rsint_exit          ; All done
  62.  
  63. ;==========================================================================;
  64. ; Drop RTS/DTR handshaking                                                 ;
  65. ;==========================================================================;
  66.  
  67. rsint_8250_droprts:
  68.  
  69.         MOV     DX,baseaddr[SI]     ; Get base address for chip
  70.         ADD     DX,mcr_8250         ; Select MCR
  71.         MOV     AL,hoff_8250        ; Turn off sending from distant end
  72.         OUT     DX,AL               ;
  73.  
  74.         OR      flags[SI],flags_useoff ; Signal user wants handshake off
  75.  
  76.         JMP     rsint_exit          ; All done
  77.  
  78. ;==========================================================================;
  79. ; Turn on RTS/DTR handshaking                                              ;
  80. ;==========================================================================;
  81.  
  82. rsint_8250_raiserts:
  83.  
  84.         MOV     DX,baseaddr[SI]     ; Get base address for chip
  85.         ADD     DX,mcr_8250         ;
  86.         MOV     AL,hon_8250         ; Raise DTR, RTS, and OUT2.  OUT2 turns
  87.         OUT     DX,AL               ; on interrupts.
  88.  
  89.         AND     flags[SI],0FFH-flags_useoff ; Turn off force handshake flag
  90.  
  91.         JMP     rsint_exit          ; All done
  92.  
  93. ;==========================================================================;
  94. ; Break!                                                                   ;
  95. ;==========================================================================;
  96.  
  97. rsint_8250_sendbrk:
  98.  
  99. ;--------------------------------------------------------------------------;
  100. ; First we see if we are going to use a hardware break or a                ;
  101. ; simulated break using three control "C"                                  ;
  102. ;--------------------------------------------------------------------------;
  103.  
  104.         TEST    options[SI],opt_brktr ; Translate break to control "C"
  105.         JNZ     rsint_8250_sendbrk_tr ;      Yep!
  106.  
  107. ;--------------------------------------------------------------------------;
  108. ; Hardware break.  Set the bit in the LCR (without disturbing the rest     ;
  109. ; and then loop for a while                                                ;
  110. ;--------------------------------------------------------------------------;
  111.  
  112.         PUSH    ES                  ; We are going to use ES, so save it
  113.         MOV     AX,040H             ; Point ES down to the BIOS region
  114.         MOV     ES,AX
  115.  
  116.         MOV     DX,baseaddr[SI]     ; Get base address for chip
  117.         ADD     DX,lcr_8250         ; Select LCR
  118.         IN      AL,DX               ; Read LCR
  119.         PUSH    AX                  ;       and save it
  120.  
  121.         OR      AL,lcr_8250_sb      ; Force on the SET BREAK bit
  122.         OUT     DX,AL               ;       and output the SET BREAK bit
  123.  
  124. rsint_8250_sendbrk_too_big:
  125.  
  126.         MOV     CX, WORD PTR ES:[006Ch] ; Get current time tick count
  127.         MOV     BX,CX                   ; Save it in bx
  128.         ADD     CX,4                    ; Calc target end-of-loop tick count
  129.  
  130.         CMP     CX, BX                  ; Will it roll over?
  131.         JB      rsint_8250_sendbrk_lp2  ;      Yep...
  132.  
  133. ; CX > BX.  No rollover needed
  134. ; If tick is not between bx and cx, then exit loop
  135.  
  136. rsint_8250_sendbrk_lp1:
  137.  
  138.         MOV     AX,WORD PTR es:[006Ch]  ; Get time tick
  139.  
  140.         CMP     AX,CX                   ; Has tick past target?
  141.         JA      rsint_8250_sendbrk_done ;      Yep, done
  142.  
  143.         CMP     AX,BX                   ; Has tick rolled over?
  144.         JB      rsint_8250_sendbrk_done ;      Yep, done
  145.  
  146.         JMP     rsint_8250_sendbrk_lp1  ; Need to loop
  147.  
  148. ; CX < BX -- We will roll over
  149. ; If tick is not outside BX and CX, then exit loop
  150.  
  151. rsint_8250_sendbrk_lp2:
  152.  
  153.         MOV     AX,WORD PTR es:[006Ch]  ; Get time tick
  154.  
  155.         CMP     AX,CX                   ; Has tick past target?
  156.         JB      rsint_8250_sendbrk_lp2  ;      Nope, loop
  157.  
  158.         CMP     AX,BX                   ; Has tick past target?
  159.         JAE     rsint_8250_sendbrk_lp2  ;      Nope, loop
  160.  
  161. ; Break is complete
  162.  
  163. rsint_8250_sendbrk_done:
  164.  
  165.         POP     AX                  ; Retrieve the lcr status
  166.         OUT     DX,AL               ;       and output it
  167.  
  168.         POP     ES                  ; Retrieve ES
  169.  
  170.         JMP     rsint_exit          ; All done
  171.  
  172. ;--------------------------------------------------------------------------;
  173. ; Translated break.  Send three control-C in a row                         ;
  174. ;--------------------------------------------------------------------------;
  175.  
  176. rsint_8250_sendbrk_tr:
  177.  
  178.         MOV     BX,baseaddr[SI]     ; Get base address for chip
  179.         MOV     CX,3                ; Three characters wanted
  180.         MOV     AH,03H              ; Control-C
  181.  
  182. ;--------------------------------------------------------------------------;
  183. ; Loop thru here 3 times                                                   ;
  184. ;--------------------------------------------------------------------------;
  185.  
  186. rsint_8250_sendbrk_loop1:           ;
  187.  
  188. ;--------------------------------------------------------------------------;
  189. ; Loop waiting for TBE                                                     ;
  190. ;--------------------------------------------------------------------------;
  191.  
  192.         MOV     DX,BX               ; Compute port address for the LSR
  193.         ADD     DX,lsr_8250         ;
  194.  
  195. rsint_8250_sendbrk_loop2:           ; Loop here until we can send
  196.  
  197.         IN      AL,DX               ; Get the LSR into AX
  198.         TEST    AL,lsr_8250_thre    ; THR empty?
  199.         JZ      rsint_8250_sendbrk_loop2  ;   No.. Loop back
  200.  
  201. ;--------------------------------------------------------------------------;
  202. ; Out the character                                                        ;
  203. ;--------------------------------------------------------------------------;
  204.  
  205.         MOV     AL,AH               ; Get ready to out character
  206.  
  207.         MOV     DX,BX               ; Compute port address for the THR
  208.         ADD     DX,thr_8250         ;      and then
  209.         OUT     DX,AL               ;      out the character
  210.  
  211. ;--------------------------------------------------------------------------;
  212. ; Loop through all three characters                                        ;
  213. ;--------------------------------------------------------------------------;
  214.  
  215.         LOOP    rsint_8250_sendbrk_loop1  ; If not done then loop back
  216.  
  217.         JMP     rsint_exit          ; All done
  218.  
  219. ;==========================================================================;
  220. ; Non destructive read                                                     ;
  221. ;==========================================================================;
  222.  
  223. rsint_8250_ndr:
  224.  
  225. ;--------------------------------------------------------------------------;
  226. ; Get the current character in the buffer.  Make no check for character    ;
  227. ; ready                                                                    ;
  228. ;--------------------------------------------------------------------------;
  229.  
  230.         MOV     BX,buffer_r_out[SI] ; Get buffer output pointer
  231.         MOV     ES,buffer_r_a[SI]   ; Get buffer segment
  232.         MOV     AL,ES:[BX]          ; Get character from buffer..
  233.  
  234. ;--------------------------------------------------------------------------;
  235. ; Set the status byte.                                                     ;
  236. ;--------------------------------------------------------------------------;
  237.  
  238.         MOV     AH,last_rs[SI]      ; Get last LSR from receive
  239.         AND     AH,0FFH-lsr_8250_dr ; Remove data ready bit
  240.         CMP     BX,buffer_r_in[SI]  ; Anything left in buffer?
  241.         JE      rsint_8250_ndr_go   ;      Nope so leave
  242.         OR      AH,lsr_8250_dr      ; Turn on data ready
  243.  
  244. rsint_8250_ndr_go:                  ;
  245.  
  246.         JMP     rsint_exit          ; All done
  247.  
  248. ;==========================================================================;
  249. ; Set option byte                                                          ;
  250. ;==========================================================================;
  251.  
  252. rsint_8250_sopt:                    ;
  253.  
  254.         XCHG    AL,options[SI]      ;
  255.  
  256.         JMP     rsint_exit          ; All done
  257.  
  258. ;==========================================================================;
  259. ; Block write                                                              ;
  260. ;==========================================================================;
  261.  
  262. rsint_8250_buffw:                   ;
  263.  
  264.         TEST    options[SI],opt_trbuf ; Transmit buffering turned on?
  265.         JNZ     rsint_8250_bufw_bw  ;        Yes.. go there now!
  266.  
  267. ;--------------------------------------------------------------------------;
  268. ; Unbuffered block write                                                   ;
  269. ;--------------------------------------------------------------------------;
  270.  
  271. ;--------------------------------------------------------------------------;
  272. ; Get the user's parameters and initialize                                 ;
  273. ;--------------------------------------------------------------------------;
  274.  
  275.         MOV     BX,SP               ; Need access to stack
  276.         MOV     DI,SS:stack_di[BX]  ; Get the offset
  277.         MOV     ES,SS:stack_es[BX]  ; Get the displacement
  278.         MOV     BX,SS:stack_cx[BX]  ; Get the size to send
  279.         MOV     CX,baseaddr[SI]     ; Get base address for chip
  280.  
  281. ;--------------------------------------------------------------------------;
  282. ; Loop sending                                                             ;
  283. ;--------------------------------------------------------------------------;
  284.  
  285. rsint_8250_bufw_ubw:
  286.  
  287.         MOV     AH,ES:[DI]          ; Get character to send
  288.         CALL    rsint_8250_send_unb ; Send it
  289.  
  290.         INC     DI                  ; Bump pointer
  291.         DEC     BX                  ; -1 from count
  292.         JNZ     rsint_8250_bufw_ubw ; Loop back
  293.  
  294. ;--------------------------------------------------------------------------;
  295. ; Store results and exit                                                   ;
  296. ;--------------------------------------------------------------------------;
  297.  
  298.         SUB     AX,AX               ; Need a zero
  299.         MOV     BX,SP               ; Need access to stack
  300.         MOV     SS:stack_di[BX],DI  ; Set the offset
  301.         MOV     SS:stack_cx[BX],AX  ; Set the count remaining(0)
  302.  
  303.         JMP     rsint_8250_status   ; Do a status
  304.  
  305. ;--------------------------------------------------------------------------;
  306. ; Buffered block write                                                     ;
  307. ;--------------------------------------------------------------------------;
  308.  
  309. rsint_8250_bufw_bw:                 ;
  310.  
  311. ;--------------------------------------------------------------------------;
  312. ; Get the user's parameters and initialize                                 ;
  313. ;--------------------------------------------------------------------------;
  314.  
  315.         MOV     BX,SP               ; Need access to stack
  316.         MOV     DX,SS:stack_cx[BX]  ; Get the size to move
  317.         MOV     DI,buffer_t_in[SI]  ; Get buffer input pointer
  318.  
  319.         AND     flags[SI],0FFH-flags_was_e ; Turn off buffer empty flag
  320.  
  321.         OR      DX,DX               ; Anything to send?
  322.         JNZ     rsint_8250_bufw_loop;     Yep
  323.  
  324.         CALL    rsint_8250_bufw_int ; Cause a hardware interrupt
  325.         JMP     rsint_8250_bufw_end ;     Nope
  326.  
  327. ;--------------------------------------------------------------------------;
  328. ; This is the loop to move data to the buffer                              ;
  329. ;       DI = input buffer position.                                        ;
  330. ;       DX = count left to move                                            ;
  331. ;--------------------------------------------------------------------------;
  332.  
  333. rsint_8250_bufw_loop:               ; Move to buffer loop
  334.  
  335. ;--------------------------------------------------------------------------;
  336. ; See if the buffer has gone empty and remember that.  If it has then      ;
  337. ; we will need to kick the interrupt servicer                              ;
  338. ;--------------------------------------------------------------------------;
  339.  
  340.         MOV     AX,buffer_t_out[SI] ; See where the out pointer is
  341. ;       CMP     AX,DI               ; Are they the same (empty buffer)
  342. ;       JNE     rsint_8250_bufw_ne  ;     No.... Buffer has something in it
  343. ;       OR      flags[SI],flags_was_e ;   Yes... Turn on buffer empty flag
  344. rsint_8250_bufw_ne:
  345.  
  346. ;--------------------------------------------------------------------------;
  347. ; Now get the space left in the buffer.                                    ;
  348. ;--------------------------------------------------------------------------;
  349.  
  350.         CMP     AX,DI               ; Is the buffer wrapped?
  351.         JG      rsint_8250_bufw_nw  ;      Not wrapped
  352.         MOV     CX,AX               ; Save AX
  353.         MOV     AX,buffer_size+1    ; Locate buffer_end + 1 for now
  354.         JCXZ    rsint_8250_bufw_nw  ; Was AX zero?
  355.         DEC     AX                  ;
  356. rsint_8250_bufw_nw:
  357.  
  358.         SUB     AX,DI               ; AX = space left in buffer
  359.         JNZ     rsint_8250_bufw_ok  ;      Space is left!
  360.         JMP     rsint_8250_bufw_end ;      No space left.. Its over
  361. rsint_8250_bufw_ok:
  362.  
  363. ;--------------------------------------------------------------------------;
  364. ; Now calculate the size to move in this iteration.                        ;
  365. ; It will be the smallest of:                                              ;
  366. ;    1)  Buffer space (now in AX)                                          ;
  367. ;    2)  Data size (now in DX)                                             ;
  368. ;--------------------------------------------------------------------------;
  369.  
  370.         CMP     AX,DX               ;
  371.         JLE     rsint_8250_bufw_m1  ;
  372.         MOV     AX,DX               ;
  373. rsint_8250_bufw_m1:                 ;
  374.  
  375. ;       CMP     AX,31               ; 63 bytes per move
  376. ;       JLE     rsint_8250_bufw_m2  ;
  377. ;       MOV     AX,31               ; Move only 63
  378. rsint_8250_bufw_m2:                 ;
  379.  
  380.  
  381. ;--------------------------------------------------------------------------;
  382. ; Update the counters                                                      ;
  383. ;--------------------------------------------------------------------------;
  384.  
  385.         SUB     DX,AX               ; Drop the count to be moved by this move.
  386.  
  387. ;--------------------------------------------------------------------------;
  388. ; Prep all the registers and do the move                                   ;
  389. ;--------------------------------------------------------------------------;
  390.  
  391.         ASSUME  DS:NOTHING;
  392.  
  393.         MOV     CX,AX               ; Get count
  394.         MOV     AX,SI               ; Save SI
  395.         MOV     ES,buffer_t_a[SI]   ; Get buffer segment
  396.         MOV     DS,SS:stack_es[BX]  ; Get input segment
  397.         MOV     SI,SS:stack_di[BX]  ; Get input offset
  398. ;       CLI
  399.         CLD                         ; The counter should go up!
  400.         REP     MOVSB               ; Do the move
  401.         MOV     SS:stack_di[BX],SI  ; Put back updated offset.
  402.         MOV     SI,AX               ; Restore SI
  403.         MOV     CX,CS               ; Restore DS
  404.         MOV     DS,CX               ;
  405. ;       STI
  406.  
  407.       ASSUME DS: everything         ;
  408.  
  409. ;--------------------------------------------------------------------------;
  410. ; Update the counters                                                      ;
  411. ;--------------------------------------------------------------------------;
  412.  
  413.         CMP     DI,buffer_size      ; Wrap the input pointer around the
  414.         JL      rsint_8250_bufw_now ; buffer if necessary
  415.         SUB     DI,DI               ;
  416. rsint_8250_bufw_now:                ;
  417.  
  418. ;--------------------------------------------------------------------------;
  419. ; See if the buffer is empty disregarding what we just put int it.         ;
  420. ; we will need to kick the interrupt servicer                              ;
  421. ;--------------------------------------------------------------------------;
  422.  
  423.         MOV     AX,buffer_t_in[SI]  ; See where the "old" input pointer is
  424.         MOV     buffer_t_in[SI],DI  ; Save "new" input pointer
  425.         CMP     AX,buffer_t_out[SI] ; See where the out pointer is
  426.         JNE     rsint_8250_bufw_noi ;          Not the same.  Buffer still ok
  427. ;       TEST    flags[SI],flags_was_e ;   Was it empty
  428. ;       JZ      rsint_8250_bufw_noi ;          Not the same.  Buffer still ok
  429.  
  430. ;--------------------------------------------------------------------------;
  431. ; If buffer was empty, cause a false hardware interrupt by setting the IIR ;
  432. ; to zero and then back.  This will cause an THR empty interrupt.          ;
  433. ;--------------------------------------------------------------------------;
  434.  
  435.         CALL    rsint_8250_bufw_int
  436.  
  437. rsint_8250_bufw_noi:                ;
  438.  
  439. ;--------------------------------------------------------------------------;
  440. ; Finish up and get ready to loop again                                    ;
  441. ;--------------------------------------------------------------------------;
  442.  
  443.         OR      DX,DX               ; Anything more to send?
  444.         JZ      rsint_8250_bufw_end ;     Nope
  445.  
  446.         JMP     rsint_8250_bufw_loop; Go loop
  447.  
  448. ;--------------------------------------------------------------------------;
  449. ; Here is where we end                                                     ;
  450. ;--------------------------------------------------------------------------;
  451.  
  452. rsint_8250_bufw_end:                ;
  453.         MOV     buffer_t_in[SI],DI  ; Save input pointer
  454.         MOV     SS:stack_cx[BX],DX  ; Bytes remaining
  455.  
  456.         JMP     rsint_8250_status   ; Do a status
  457.  
  458. ;==========================================================================;
  459. ; Case a false hardware interrupt on the chip.                             ;
  460. ;==========================================================================;
  461.  
  462. ;--------------------------------------------------------------------------;
  463. ; If buffer was empty, cause a false hardware interrupt by setting the IIR ;
  464. ; to zero and then back.  This will cause an THR empty interrupt.          ;
  465. ;--------------------------------------------------------------------------;
  466.  
  467. rsint_8250_bufw_int:
  468.  
  469. ;       MOV     AL,hiv[SI]          ; Get the hardware interrupt vector address
  470. ;       MOV     rsint_8250_bufw_int,AL ; Put it where we need it
  471. ;       JMP     $+2                 ; Flush interrupt buffer
  472. ;       INT     00H                 ; Interrupt!
  473. ;       ORG     $-1
  474. ;sint_8250_bufw_int DB  ?           ; Place to put interrupt number
  475. ;
  476.  
  477.         CLI                         ; No interrupt please!
  478.  
  479.         MOV     CX,DX               ; Save DX
  480.  
  481.         MOV     DX,baseaddr[SI]     ; Get base address for chip
  482.         ADD     DX,ier_8250         ; Address IER
  483.         IN      AL,DX               ; Get it
  484.         MOV     AH,AL               ; Save it
  485.         SUB     AL,AL               ; Now send zero
  486.         OUT     DX,AL               ;      to IER
  487.         MOV     AL,AH               ; Now restore IER
  488.         JMP     $+2                 ; Delay
  489.         OUT     DX,AL               ;
  490.         JMP     $+2                 ; Delay
  491.         STI                         ; Enable
  492.  
  493.         MOV     DX,CX               ; Restore DX
  494.  
  495.         RET
  496.  
  497. ;==========================================================================;
  498. ; Block read                                                               ;
  499. ;==========================================================================;
  500.  
  501. rsint_8250_buffr:                   ;
  502.  
  503. ;--------------------------------------------------------------------------;
  504. ; Initialize                                                               ;
  505. ;--------------------------------------------------------------------------;
  506.  
  507.         MOV     BX,SP               ; Need pointer for stack
  508.         SUB     DX,DX               ; Number of bytes moved.
  509.  
  510. ;--------------------------------------------------------------------------;
  511. ; This is the main move loop                                               ;
  512. ;       DX = total_bytes moved                                             ;
  513. ;--------------------------------------------------------------------------;
  514.  
  515. rsint_8250_bufr_loop:
  516.  
  517. ;--------------------------------------------------------------------------;
  518. ; If no data left then we can leave                                        ;
  519. ;--------------------------------------------------------------------------;
  520.  
  521.         MOV     DI,buffer_r_out[SI] ; Get buffer output pointer
  522.         MOV     AX,buffer_r_in[SI]  ; Get buffer input pointer
  523.         CMP     AX,DI               ; See in anything in buffer
  524.         JE      rsint_8250_bufr_done ;     Nope.. Quit
  525.  
  526. ;--------------------------------------------------------------------------;
  527. ; Now get the data left in the buffer.                                     ;
  528. ;--------------------------------------------------------------------------;
  529.  
  530.         MOV     CX,AX               ; CX = end of area to move
  531.         CMP     AX,DI               ; Is the buffer wrapped?
  532.         JGE     rsint_8250_bufr_nw  ;      Not wrapped
  533.         MOV     CX,buffer_size      ;      Wrapped.  Locate end for now
  534. rsint_8250_bufr_nw:
  535.  
  536.         SUB     CX,DI               ; CX = data left in buffer
  537.  
  538.         MOV     AX,SS:stack_cx[BX]  ; Get user's buffer size
  539.         OR      AX,AX               ; Any space left?
  540.         JZ      rsint_8250_bufr_done ;     Nope.. Quit
  541.  
  542. ;--------------------------------------------------------------------------;
  543. ; Now calculate the size to move in this iteration.                        ;
  544. ; It will be the smallest of:                                              ;
  545. ;    1)  Data size (now in CX)                                             ;
  546. ;    2)  User's buffer size                                                ;
  547. ;--------------------------------------------------------------------------;
  548.  
  549.         CMP     CX,AX               ;
  550.         JLE     rsint_8250_bufr_m1  ;
  551.         MOV     CX,AX               ;
  552. rsint_8250_bufr_m1:                 ;
  553.  
  554. ;--------------------------------------------------------------------------;
  555. ; Update counters now                                                      ;
  556. ;--------------------------------------------------------------------------;
  557.  
  558.         ADD     DX,CX               ; Bump bytes moved counter
  559.         SUB     AX,CX               ; Show buffer usage
  560.         MOV     SS:stack_cx[BX],AX  ; And store back
  561.  
  562. ;--------------------------------------------------------------------------;
  563. ; Prep all the registers and do the move                                   ;
  564. ;--------------------------------------------------------------------------;
  565.  
  566.         ASSUME  DS:NOTHING;
  567.  
  568.         MOV     AX,SI               ; Save SI
  569.         MOV     DS,buffer_r_a[SI]   ; Get buffer segment
  570.         MOV     SI,DI               ; Set buffer offset
  571.         MOV     ES,SS:stack_es[BX]  ; Get input segment
  572.         MOV     DI,SS:stack_di[BX]  ; Get input offset
  573.         CLD                         ; The counter should go up!
  574.         REP     MOVSB               ; Do the move
  575.         MOV     SS:stack_di[BX],DI  ; Put back updated offset.
  576.         MOV     DI,SI               ; Restore an updated DI
  577.         MOV     SI,AX               ; Restore SI
  578.         MOV     AX,CS               ; Restore DS
  579.         MOV     DS,AX               ;
  580.  
  581.       ASSUME DS: everything         ;
  582.  
  583. ;--------------------------------------------------------------------------;
  584. ; Update things                                                            ;
  585. ;--------------------------------------------------------------------------;
  586.  
  587.         CMP     DI,buffer_size      ; Wrap the input pointer around the
  588.         JL      rsint_8250_bufr_now ; buffer if necessary
  589.         SUB     DI,DI               ;
  590. rsint_8250_bufr_now:                ;
  591.         MOV     buffer_r_out[SI],DI ; Set buffer output pointer
  592.  
  593. ;--------------------------------------------------------------------------;
  594. ; Loop back                                                                ;
  595. ;--------------------------------------------------------------------------;
  596.  
  597.         JMP     rsint_8250_bufr_loop ;
  598.  
  599. ;--------------------------------------------------------------------------;
  600. ; Here is where we end                                                     ;
  601. ;--------------------------------------------------------------------------;
  602.  
  603. rsint_8250_bufr_done :              ;
  604.  
  605.         MOV     BX,SP               ; Use SP in BX
  606.         MOV     SS:stack_cx[BX],DX  ; Bytes moved
  607.  
  608.         JMP     rsint_8250_status   ; Do a status
  609.  
  610. ;==========================================================================;
  611. ; WA8DED Mode                                                              ;
  612. ;==========================================================================;
  613.  
  614. rsint_8250_ded:                     ;
  615.  
  616.         JMP     rsint_exit          ; All done
  617.